// inmp441_driver_d.cpp
#include "inmp441_driver_d.h"
#include <TFT_eSPI.h>
#include <driver/i2s.h>

// ----------------- ST7789 -----------------
TFT_eSPI tft = TFT_eSPI();
#define WIDTH 240
#define HEIGHT 240

// ----------------- INMP441 -----------------
#define I2S_WS   25   // LRCLK
#define I2S_SCK  26   // BCLK
#define I2S_SD   22   // DATA

#define I2S_NUM       I2S_NUM_0
#define SAMPLE_RATE   44100
#define I2S_BITS      I2S_BITS_PER_SAMPLE_32BIT
#define DMA_BUF_COUNT 8
#define DMA_BUF_LEN   128

#define NUM_BARS 8   // 柱子数量

int32_t buffer[DMA_BUF_LEN];
uint32_t maxVolume = 1000000; // 初始最大音量，可调

/**
 * 初始化 INMP441 与屏幕
 */
void inmp441Setup_d() {
    Serial.begin(115200);
    tft.init();
    tft.setRotation(2);
    tft.fillScreen(TFT_BLACK);

    tft.setTextColor(TFT_WHITE);
    tft.setTextSize(2);
    tft.setCursor(20, 20);
    tft.print("蹦迪准备中...");

    // I2S 配置
    i2s_config_t i2s_config = {};
    i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX);
    i2s_config.sample_rate = SAMPLE_RATE;
    i2s_config.bits_per_sample = I2S_BITS;
    i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT;
    i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S;
    i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;
    i2s_config.dma_buf_count = DMA_BUF_COUNT;
    i2s_config.dma_buf_len = DMA_BUF_LEN;
    i2s_config.use_apll = false;
    i2s_config.tx_desc_auto_clear = false;
    i2s_config.fixed_mclk = 0;

    i2s_pin_config_t pin_config = {};
    pin_config.bck_io_num = I2S_SCK;
    pin_config.ws_io_num = I2S_WS;
    pin_config.data_out_num = I2S_PIN_NO_CHANGE;
    pin_config.data_in_num = I2S_SD;

    i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
    i2s_set_pin(I2S_NUM, &pin_config);

    Serial.println("INMP441 已初始化完成");
}

/**
 * 获取缓冲区平均音量
 */
uint32_t getVolume(int32_t* buf, size_t len) {
    uint64_t sum = 0;
    for (size_t i = 0; i < len; i++) {
        int32_t sample = buf[i];
        sum += (sample > 0 ? sample : -sample);
    }
    return sum / len;
}

/**
 * 绘制多柱音量条
 */
void drawBars(int32_t* samples, size_t len) {
    int barWidth = WIDTH / NUM_BARS;
    for (int i = 0; i < NUM_BARS; i++) {
        uint64_t sum = 0;
        int samplesPerBar = len / NUM_BARS;
        for (int j = 0; j < samplesPerBar; j++) {
            sum += abs(samples[i * samplesPerBar + j]);
        }
        int barHeight = map(sum / samplesPerBar, 0, maxVolume, 0, HEIGHT);
        if (barHeight > HEIGHT) barHeight = HEIGHT;

        // 左右柱子留 2px 间距
        tft.fillRect(i * barWidth, HEIGHT - barHeight, barWidth - 2, barHeight, TFT_GREEN);
    }
}

/**
 * 循环读取麦克风并显示多柱音量条
 */
void inmp441Loop_d() {
    size_t bytesRead = 0;
    if (i2s_read(I2S_NUM, buffer, sizeof(buffer), &bytesRead, portMAX_DELAY) == ESP_OK && bytesRead > 0) {
        // 清屏
        tft.fillScreen(TFT_BLACK);

        // 绘制柱状图
        drawBars(buffer, DMA_BUF_LEN);

        // 打印平均音量到串口
        uint32_t avgVol = getVolume(buffer, DMA_BUF_LEN);
        Serial.print("平均音量: ");
        Serial.println(avgVol);
    }
}